﻿
/**************************************************************************
*   
*   =================================
*   CLR版本    ：4.0.30319.42000
*   命名空间    ：sm4
*   文件名称    ：Sm4Crypto.cs
*   =================================
*   创 建 者    ：wxy
*   创建日期    ：2022/5/24 16:05:29 
*   邮箱        ：
*   个人主站    ：
*   功能描述    ：
*   使用说明    ：
*   =================================
*   修改者    ：wxy
*   修改日期    ：
*   修改内容    ：
*   =================================
*  
***************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Org.BouncyCastle.Utilities.Encoders; 

namespace sm4
{
    public class Sm4Crypto
    {
        public string secretKey = ""; //为空 , 调用传递过来
        public string iv = "0000000000000000";
        public bool hexString = false;

        #region ECB模式加密
        /// <summary>
        /// ECB模式加密
        /// </summary>
        /// <param name="plainText">需要加密的串</param>
        /// <returns></returns>
        public byte[] Encrypt_ECB(string plainText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, Encoding.Default.GetBytes(plainText));

            return Hex.Encode(encrypted);
        }

        /// <summary>
        /// ECB模式加密
        /// </summary>
        /// <param name="plainBytes"></param>
        /// <returns></returns>
        public byte[] Encrypt_ECB(byte[] plainBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainBytes);

            return Hex.Encode(encrypted);
        }
        /// <summary>
        /// ECB模式加密
        /// </summary>
        /// <param name="plainText">待加密的明文串{phone:"13800138000",captcha:"484577"}</param>
        /// <returns></returns>
        public string Encrypt_ECB_Str(string plainText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, Encoding.Default.GetBytes(plainText));

            return Encoding.Default.GetString(Hex.Encode(encrypted));
        }
        /// <summary>
        /// ECB模式加密
        /// </summary>
        /// <param name="plainBytes"></param>
        /// <returns></returns>
        public string Encrypt_ECB_Str(byte[] plainBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainBytes);

            return Encoding.Default.GetString(Hex.Encode(encrypted));
        }
        #endregion

        #region ECB模式解密
        /// <summary>
        /// ECB模式解密
        /// </summary>
        /// <param name="cipherText">需要解密的串</param>
        /// <returns></returns>
        public byte[] Decrypt_ECB(string cipherText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Hex.Decode(cipherText));
            return decrypted;
        }

        /// <summary>
        /// ECB模式解密
        /// </summary>
        /// <param name="plainBytes"></param>
        /// <returns></returns>
        public byte[] Decrypt_ECB(byte[] cipherBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Hex.Decode(cipherBytes));
            return decrypted;
        }

        /// <summary>
        /// ECB模式解密
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public string Decrypt_ECB_Str(string cipherText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
           //  byte[] str2Hex = Encoding.UTF8.GetBytes(cipherText);
            byte[] str2Hex = Hex.Decode(cipherText);
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, str2Hex );
            string result = Encoding.UTF8.GetString(decrypted);
            Console.WriteLine(result);
            return result;
        }

        /// <summary>
        /// ECB模式解密
        /// </summary>
        /// <param name="plainBytes"></param>
        /// <returns></returns>
        public string Decrypt_ECB_Str(byte[] cipherBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Hex.Decode(cipherBytes));
            return Encoding.Default.GetString(decrypted);
        }
        #endregion

        #region CBC模式加密
        /// <summary>
        /// CBC模式加密
        /// </summary>
        /// <param name="plainText"></param>
        /// <returns></returns>
        public byte[] Encrypt_CBC(string plainText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Encoding.Default.GetBytes(plainText));

            return Hex.Encode(encrypted);
        }

        /// <summary>
        /// CBC模式加密
        /// </summary>
        /// <param name="plainBytes"></param>
        /// <returns></returns>
        public byte[] Encrypt_CBC(byte[] plainBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainBytes);

            return Hex.Encode(encrypted);
        }

        /// <summary>
        /// CBC模式加密
        /// </summary>
        /// <param name="plainText"></param>
        /// <returns></returns>
        public string Encrypt_CBC_Str(string plainText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Encoding.Default.GetBytes(plainText));

            return Encoding.Default.GetString(Hex.Encode(encrypted));
        }

        /// <summary>
        /// CBC模式加密
        /// </summary>
        /// <param name="plainBytes"></param>
        /// <returns></returns>
        public string Encrypt_CBC_Str(byte[] plainBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_ENCRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainBytes);

            return Encoding.Default.GetString(Hex.Encode(encrypted));
        }
        #endregion

        #region CBC模式解密
        /// <summary>
        /// CBC模式解密
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public byte[] Decrypt_CBC(string cipherText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherText));
            return decrypted;
        }

        /// <summary>
        /// CBC模式解密
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public byte[] Decrypt_CBC(byte[] cipherBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherBytes));
            return decrypted;
        }
        /// <summary>
        /// CBC模式解密
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public string Decrypt_CBC_Str(string cipherText)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherText));
            return Encoding.Default.GetString(decrypted);
        }

        /// <summary>
        /// CBC模式解密
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public string Decrypt_CBC_Str(byte[] cipherBytes)
        {
            SM4Context ctx = new SM4Context();
            ctx.isPadding = true;
            ctx.mode = SM4Secret.SM4_DECRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Hex.Decode(secretKey);
                ivBytes = Hex.Decode(iv);
            }
            else
            {
                keyBytes = Encoding.Default.GetBytes(secretKey);
                ivBytes = Encoding.Default.GetBytes(iv);
            }

            SM4Secret sm4 = new SM4Secret();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherBytes));
            return Encoding.Default.GetString(decrypted);
        }
        #endregion
    }

}
